package com.crypt.properties.factory;

import com.crypt.properties.algorithm.CryptAlgorithm;
import com.crypt.properties.exception.CryptPropertiesException;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CryptFactory {

    private CryptFactory() {
    }

    private enum CryptFactoryHolder {
        INSTANCE;
        private final CryptFactory instance;

        CryptFactoryHolder() {
            this.instance = new CryptFactory();
        }

        private CryptFactory getInstance() {
            return this.instance;
        }
    }

    private final Map<String, CryptAlgorithm> cryptAlgorithmMap = new ConcurrentHashMap<>();

    public static CryptFactory instance() {
        return CryptFactoryHolder.INSTANCE.getInstance();
    }

    public void addCryptAlgorithm(String algorithm, CryptAlgorithm cryptAlgorithm) {
        cryptAlgorithmMap.put(algorithm, cryptAlgorithm);
    }

    public String decrypt(String algorithm, String encrypted, Map<String, Object> properties) {
        CryptAlgorithm cryptAlgorithm = cryptAlgorithmMap.get(algorithm);
        if (cryptAlgorithm == null) {
            throw new CryptPropertiesException("\"" + algorithm + "\" is not support.");
        }
        cryptAlgorithm.setProperties(properties);
        return cryptAlgorithm.decrypt(encrypted);
    }

}
